package com.example.commonmistak.designpatterns.reflection;

import com.example.commonmistak.designpatterns.reflection.anno.BankApi;
import com.example.commonmistak.designpatterns.reflection.anno.BankApiField;
import com.example.commonmistak.designpatterns.reflection.api.AbstractApi;
import com.example.commonmistak.designpatterns.reflection.api.CreateUserApi;
import com.example.commonmistak.designpatterns.reflection.api.PayApi;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.Comparator;

/**
 * @author xiongwei
 * @date 2022/1/19 14:19
 */
@Slf4j
public class ReflectionDemo {


    public static void main(String[] args) {
        CreateUserApi api = new CreateUserApi();
        api.setName("xiaoMing");
        api.setAge(18);
        api.setMobile("mobile");
        api.setIdentity("identity");
        remoteCall(api);

        PayApi payApi = new PayApi();
        payApi.setId(123L);
        payApi.setAmount(new BigDecimal("9.9"));
        remoteCall(payApi);
    }


    public static String remoteCall(AbstractApi api) {
        BankApi bankApi = api.getClass().getAnnotation(BankApi.class);
        String url = bankApi.url();

        StringBuilder sb = new StringBuilder();

        //获取所以字段
        Field[] declaredFields = api.getClass().getDeclaredFields();
        Arrays.stream(declaredFields)
                //查找注解字段
                .filter(field -> field.isAnnotationPresent(BankApiField.class))
                //根据注解 order 属性排序
                .sorted(Comparator.comparingInt(field -> field.getAnnotation(BankApiField.class).order()))
                //设置私有属性可访问
                .peek(field -> field.setAccessible(true))
                .forEach(field -> {
                    BankApiField bankApiField = field.getAnnotation(BankApiField.class);
                    Object value = "";
                    try {
                        value = field.get(api);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }

                    int length = bankApiField.length();
                    switch (bankApiField.type()) {
                        case "S":
                            sb.append(String.format("%-" + length + "s", value.toString()).replace(" ", "_"));
                            break;
                        case "N":
                            sb.append(String.format("%" + length + "s", value.toString()).replace(" ", "0"));
                            break;
                        case "M":
                            if (!(value instanceof BigDecimal)) {
                                throw new RuntimeException(String.format("{} 的 {} 必须是BigDecimal", api, field));
                            }
                            long longValue = ((BigDecimal) value).setScale(2, RoundingMode.DOWN).multiply(new BigDecimal("100")).longValue();
                            sb.append(String.format("%0" + length + "d", longValue));
                            break;
                        default:
                    }
                });

        //可以执行 http 请求
        log.info("执行{}, url:{}, params:{}", bankApi.desc(), bankApi.url(), sb);

        return sb.toString();
    }
}
